package com.lineage.server.model.npc.action;

import com.lineage.server.datatables.ItemTable;
import com.lineage.server.model.Instance.L1ItemInstance;
import com.lineage.server.model.Instance.L1NpcInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.L1Object;
import com.lineage.server.model.L1ObjectAmount;
import com.lineage.server.model.L1PcInventory;
import com.lineage.server.model.npc.L1NpcHtml;
import com.lineage.server.serverpackets.S_HowManyMake;
import com.lineage.server.serverpackets.S_ServerMessage;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1Item;
import com.lineage.server.utils.IterableElementList;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class L1NpcMakeItemAction extends L1NpcXmlAction {
  private final List<L1ObjectAmount<Integer>> _materials;
  
  private final List<L1ObjectAmount<Integer>> _items;
  
  private final boolean _isAmountInputable;
  
  private final L1NpcAction _actionOnSucceed;
  
  private final L1NpcAction _actionOnFail;
  
  public L1NpcMakeItemAction(Element element) {
    super(element);
    this._materials = new ArrayList<>();
    this._items = new ArrayList<>();
    this._isAmountInputable = L1NpcXmlParser.getBoolAttribute(element, "AmountInputable", true);
    NodeList list = element.getChildNodes();
    Iterator<Element> iterator = (new IterableElementList(list)).iterator();
    while (iterator.hasNext()) {
      Element element1 = iterator.next();
      if (element1.getNodeName().equalsIgnoreCase("Material")) {
        int i = Integer.valueOf(element1.getAttribute("ItemId")).intValue();
        long l = Long.valueOf(element1.getAttribute("Amount")).longValue();
        this._materials.add(new L1ObjectAmount(Integer.valueOf(i), l));
        continue;
      } 
      if (!element1.getNodeName().equalsIgnoreCase("Item"))
        continue; 
      int id = Integer.valueOf(element1.getAttribute("ItemId")).intValue();
      long amount = Long.valueOf(element1.getAttribute("Amount")).longValue();
      this._items.add(new L1ObjectAmount(Integer.valueOf(id), amount));
    } 
    if (this._items.isEmpty() || this._materials.isEmpty())
      throw new IllegalArgumentException(); 
    Element elem = L1NpcXmlParser.getFirstChildElementByTagName(element, "Succeed");
    this._actionOnSucceed = (elem == null) ? null : new L1NpcListedAction(elem);
    elem = L1NpcXmlParser.getFirstChildElementByTagName(element, "Fail");
    this._actionOnFail = (elem == null) ? null : new L1NpcListedAction(elem);
  }
  
  private boolean makeItems(L1PcInstance pc, String npcName, long amount) {
    if (amount <= 0L)
      return false; 
    boolean isEnoughMaterials = true;
    Iterator<L1ObjectAmount<Integer>> iterator = this._materials.iterator();
    while (iterator.hasNext()) {
      L1ObjectAmount<Integer> material = iterator.next();
      if (!pc.getInventory().checkItemNotEquipped(((Integer)material.getObject()).intValue(), 
          material.getAmount() * amount)) {
        L1Item temp = ItemTable.get().getTemplate(((Integer)material.getObject()).intValue());
        pc.sendPackets((ServerBasePacket)new S_ServerMessage(337, String.valueOf(String.valueOf(temp.getNameId())) + "(" + (
              material.getAmount() * amount - pc.getInventory().countItems(temp.getItemId())) + ")"));
        isEnoughMaterials = false;
      } 
    } 
    if (!isEnoughMaterials)
      return false; 
    int countToCreate = 0;
    int weight = 0;
    Iterator<L1ObjectAmount<Integer>> iterator2 = this._items.iterator();
    while (iterator2.hasNext()) {
      L1ObjectAmount<Integer> makingItem = iterator2.next();
      L1Item temp2 = ItemTable.get().getTemplate(((Integer)makingItem.getObject()).intValue());
      if (temp2.isStackable()) {
        if (!pc.getInventory().checkItem(((Integer)makingItem.getObject()).intValue()))
          countToCreate++; 
      } else {
        countToCreate = (int)(countToCreate + makingItem.getAmount() * amount);
      } 
      weight = (int)(weight + temp2.getWeight() * makingItem.getAmount() * amount / 1000L);
    } 
    if (pc.getInventory().getSize() + countToCreate > 180) {
      pc.sendPackets((ServerBasePacket)new S_ServerMessage(263));
      return false;
    } 
    if (pc.getMaxWeight() < (pc.getInventory().getWeight() + weight)) {
      pc.sendPackets((ServerBasePacket)new S_ServerMessage(82));
      return false;
    } 
    Iterator<L1ObjectAmount<Integer>> iterator3 = this._materials.iterator();
    while (iterator3.hasNext()) {
      L1ObjectAmount<Integer> material2 = iterator3.next();
      pc.getInventory().consumeItem(((Integer)material2.getObject()).intValue(), material2.getAmount() * amount);
    } 
    Iterator<L1ObjectAmount<Integer>> iterator4 = this._items.iterator();
    while (iterator4.hasNext()) {
      L1ObjectAmount<Integer> makingItem = iterator4.next();
      L1ItemInstance item = pc.getInventory().storeItem(((Integer)makingItem.getObject()).intValue(), 
          makingItem.getAmount() * amount);
      if (item != null) {
        String itemName = ItemTable.get().getTemplate(((Integer)makingItem.getObject()).intValue()).getNameId();
        if (makingItem.getAmount() * amount > 1L)
          itemName = String.valueOf(String.valueOf(itemName)) + " (" + (makingItem.getAmount() * amount) + ")"; 
        pc.sendPackets((ServerBasePacket)new S_ServerMessage(143, npcName, itemName));
      } 
    } 
    return true;
  }
  
  private long countNumOfMaterials(L1PcInventory inv) {
    long count = Long.MAX_VALUE;
    Iterator<L1ObjectAmount<Integer>> iterator = this._materials.iterator();
    while (iterator.hasNext()) {
      L1ObjectAmount<Integer> material = iterator.next();
      long numOfSet = inv.countItems(((Integer)material.getObject()).intValue()) / material.getAmount();
      count = Math.min(count, numOfSet);
    } 
    return count;
  }
  
  public L1NpcHtml execute(String actionName, L1PcInstance pc, L1Object obj, byte[] args) {
    long numOfMaterials = countNumOfMaterials(pc.getInventory());
    if (1L < numOfMaterials && this._isAmountInputable) {
      pc.sendPackets((ServerBasePacket)new S_HowManyMake(obj.getId(), (int)numOfMaterials, actionName));
      return null;
    } 
    return executeWithAmount(actionName, pc, obj, 1L);
  }
  
  public L1NpcHtml executeWithAmount(String actionName, L1PcInstance pc, L1Object obj, long amount) {
    L1NpcInstance npc = (L1NpcInstance)obj;
    L1NpcHtml result = null;
    if (makeItems(pc, npc.getNameId(), amount)) {
      if (this._actionOnSucceed != null)
        result = this._actionOnSucceed.execute(actionName, pc, obj, new byte[0]); 
    } else if (this._actionOnFail != null) {
      result = this._actionOnFail.execute(actionName, pc, obj, new byte[0]);
    } 
    return (result == null) ? L1NpcHtml.HTML_CLOSE : result;
  }
  
  public void execute(String actionName, String npcid) {}
}
